# coding=utf-8
"""
功能描述：
用于搜集和管理测试用例，并启动引擎去执行测试用例，调用断言对执行结果进行判定
将执行结果写入到数据库中
"""
import time
from three_robot.robot.services.tools import pro_path
from three_robot.robot.services.dbparser import Dbparser
from three_robot.robot.services.keylibx import Keylib
from three_robot.robot.view.repoters import Repoter
from three_robot.robot.services.driver_rt import Driver
from configparser import ConfigParser


class TestPlan:

    def __init__(self, tcfile, reportfile):
        self.cfg = ConfigParser()
        self.cfg.read(pro_path('three_robot') + '/conf.ini', encoding="utf-8")
        self.sheetname = self.cfg.get('ci', 'sheetname')
        self.dbparser = Dbparser(tcfile)
        self.keylib = Keylib()
        self.reportpath = reportfile
        self.tcl = self.collect_tc()
        self.result_cl = []
        self.tid = []

    # 搜集测试用例
    def collect_tc(self):
        case_list = self.dbparser.get_cases(self.sheetname)
        return case_list

    # 实现测试用例的运行器
    def runner(self):
        '''
        功能逻辑：
        1、判断哪些用例是需要运行，哪些用例是不需要运行的
        2、判断用例的运行是否需要前置条件
        3、运行当前测试用例的步骤
            1、读取当前步骤的keyword，去keylib中找对应的方法，类反射技术
            2、把参数传递给关键字方法，启动运行
        4、收集运行结果数据
        5、输出测试报告
        '''
        tcid = []
        for tc in self.tcl:
            tcid.append(tc.tcid)

        for tc in self.tcl:
            self.result_cl.append(tc)
            prepare = tc.prepare
            # print(type(tc.flag))

            if tc.flag == '0':
                Repoter.skip += 1
                Repoter.rst.append('skip')
                continue
            elif prepare:  # 判断是否有前置步骤，如果有就需要先执行前置步骤
                # print(tcid)
                if prepare not in tcid:
                    Repoter.erro += 1
                    Repoter.rst.append('前置条件不存在')
                    print('前置条件不存在！')
                    continue
                else:
                    self.run_prepare(prepare)
                    for step in tc.steps:
                        # time.sleep(1)
                        if self.run_one_step(step):
                            pass
                        else:
                            break
                    continue
            else:
                # print(tc.steps)
                for step in tc.steps:
                    # time.sleep(1)
                    # print(step)
                    if self.run_one_step(step):
                        pass
                    else:
                        break

                # time.sleep(1)
        # Driver.get_driver().save_screenshot('../view/picture/case_repoter123.png')   #截图
        # time.sleep(1)
        # Driver.quit_driver()
        # print(tcl)
        # 生成测试报告
        # time.sleep(5)
        self.write_report()

        # Driver.quit_driver()

    # 执行一步测试用例
    def run_one_step(self, step):
        try:
            keyword = step.get('key').lower()  # 读取步骤中的关键字
            if hasattr(self.keylib, keyword):  # 判断对应的关键字方法是否存在
                func = getattr(self.keylib, keyword)  # 如果存在，则使用反射去获取该方法
                if func(self.deal_param(step)):  # 执行方法，把步骤中的参数传递给该方法
                    step['执行成功'] = keyword
                    return True
                else:
                    step['执行失败'] = keyword
                    return False
            else:
                getattr(self.keylib, keyword)
            # Repoter.erro+=1
            # Repoter.rst.append('用例编写错误！')

        except Exception as e:
            Repoter.erro += 1
            # Repoter.rst.append('用例编写错误！')
            print(e)
            Repoter.rst.append(f'Err：{e}')

    # 执行前置用例
    def run_prepare(self, tcid):
        tcl = self.collect_tc()
        for tc in tcl:
            if tc.tcid == tcid:
                for step in tc.steps:
                    # time.sleep(1)
                    if self.run_one_step(step):
                        pass
                    else:
                        break
            else:
                continue

    # 处理关键字方法的参数
    def deal_param(self, step):
        step.pop('key')
        return step

    # 输出测试报告
    def write_report(self):
        r = Repoter(pro_path('three_robot') + '/repoter.html')
        r.generate_repoter(self.result_cl)
        Driver.get_driver().get(
            pro_path('three_robot') + r'\repoter.html')
        Driver.get_driver().save_screenshot(pro_path('three_robot') + '/robot/view/picture/case_repoter.png')  # 截图
        time.sleep(1)

        # Driver.driver = None


if __name__ == '__main__':
    plan = TestPlan('../testdata/testdata.xlsx', 'report.html')
    plan.runner()
